<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <title>Pony 教程  | 概述（Overview）</title>
    <meta name="HandheldFriendly" content="True">
    <meta name="MobileOptimized" content="320">

    <meta name="viewport" content="width=device-width,minimum-scale=1">
    <meta name="generator" content="Hugo 0.69.0-DEV" />
    
    
      <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    

    <style>
      @font-face {
        font-family: 'Icon';
        src: url('/pony-tutorial/dist/fonts/icon.eot?52m981');
        src: url('/pony-tutorial/dist/fonts/icon.eot?#iefix52m981')
               format('embedded-opentype'),
             url('/pony-tutorial/dist/fonts/icon.woff?52m981')
               format('woff'),
             url('/pony-tutorial/dist/fonts/icon.ttf?52m981')
               format('truetype'),
             url('/pony-tutorial/dist/fonts/icon.svg?52m981#icon')
               format('svg');
        font-weight: normal;
        font-style: normal;
      }
    </style>

    <link href="/pony-tutorial/dist/css/app.css" rel="stylesheet">
    <link href="/pony-tutorial/dist/css/highlight.css" rel="stylesheet">
    <link href="/pony-tutorial/dist/css/icon.css" rel="stylesheet">
    <link href="/pony-tutorial/dist/css/pony.css" rel="stylesheet">

    

    
      
    

    
      <link href="https://damon-kwok.github.io/pony-tutorial/reference-capabilities/index.xml" rel="alternate" type="application/rss+xml" title="Pony 教程" />
      <link href="https://damon-kwok.github.io/pony-tutorial/reference-capabilities/index.xml" rel="feed" type="application/rss+xml" title="Pony 教程" />
    

    <meta property="og:title" content="概述（Overview）" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://damon-kwok.github.io/pony-tutorial/reference-capabilities.html" />

<meta itemprop="name" content="概述（Overview）">
<meta itemprop="description" content=""><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="概述（Overview）"/>
<meta name="twitter:description" content=""/>

  </head>

  <body class="ma0 avenir bg-near-white">

    

  <header>
    <div class="bg-pony-brown">
      <nav class="pv3 ph3 ph4-ns" role="navigation">
  <div class="flex-l justify-between items-center center">
    <a href="https://damon-kwok.github.io/pony-tutorial/" class="f3 fw2 hover-white no-underline white-90 dib">
      Pony 教程
    </a>
    <div class="flex-l items-center">
      
      
<div hidden>
  <span id="new-window-0">Opens in a new window</span>
  <span id="new-window-1">Opens an external site</span>
  <span id="new-window-2">Opens an external site in a new window</span>
</div>



<a href="https://www.twitter.com/ponylang" target="_blank" class="link-transition twitter link dib z-999 pt3 pt0-l mr1" title="Twitter link" rel="noopener" aria-describedby="new-window-0">
  <svg height="32px"  style="enable-background:new 0 0 67 67;" version="1.1" viewBox="0 0 67 67" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M37.167,22.283c-2.619,0.953-4.274,3.411-4.086,6.101  l0.063,1.038l-1.048-0.127c-3.813-0.487-7.145-2.139-9.974-4.915l-1.383-1.377l-0.356,1.017c-0.754,2.267-0.272,4.661,1.299,6.271  c0.838,0.89,0.649,1.017-0.796,0.487c-0.503-0.169-0.943-0.296-0.985-0.233c-0.146,0.149,0.356,2.076,0.754,2.839  c0.545,1.06,1.655,2.097,2.871,2.712l1.027,0.487l-1.215,0.021c-1.173,0-1.215,0.021-1.089,0.467  c0.419,1.377,2.074,2.839,3.918,3.475l1.299,0.444l-1.131,0.678c-1.676,0.976-3.646,1.526-5.616,1.568  C19.775,43.256,19,43.341,19,43.405c0,0.211,2.557,1.397,4.044,1.864c4.463,1.377,9.765,0.783,13.746-1.568  c2.829-1.673,5.657-5,6.978-8.221c0.713-1.716,1.425-4.851,1.425-6.354c0-0.975,0.063-1.102,1.236-2.267  c0.692-0.678,1.341-1.419,1.467-1.631c0.21-0.403,0.188-0.403-0.88-0.043c-1.781,0.636-2.033,0.551-1.152-0.402  c0.649-0.678,1.425-1.907,1.425-2.267c0-0.063-0.314,0.042-0.671,0.233c-0.377,0.212-1.215,0.53-1.844,0.72l-1.131,0.361l-1.027-0.7  c-0.566-0.381-1.361-0.805-1.781-0.932C39.766,21.902,38.131,21.944,37.167,22.283z M33,64C16.432,64,3,50.569,3,34S16.432,4,33,4  s30,13.431,30,30S49.568,64,33,64z" style="fill-rule:evenodd;clip-rule:evenodd;fill:;"/></svg>

<span class="new-window"><svg  height="8px"  style="enable-background:new 0 0 1000 1000;" version="1.1" viewBox="0 0 1000 1000" width="8px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<path d="M598 128h298v298h-86v-152l-418 418-60-60 418-418h-152v-86zM810 810v-298h86v298c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h298v86h-298v596h596z" style="fill-rule:evenodd;clip-rule:evenodd;fill:;"/>
</svg>
</span></a>





<a href="https://github.com/damon-kwok/pony-tutorial-zh_CN" target="_blank" class="link-transition github link dib z-999 pt3 pt0-l mr1" title="Github link" rel="noopener" aria-describedby="new-window-0">
  <svg  height="32px"  style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
  <path d="M256,32C132.3,32,32,134.8,32,261.7c0,101.5,64.2,187.5,153.2,217.9c11.2,2.1,15.3-5,15.3-11.1   c0-5.5-0.2-19.9-0.3-39.1c-62.3,13.9-75.5-30.8-75.5-30.8c-10.2-26.5-24.9-33.6-24.9-33.6c-20.3-14.3,1.5-14,1.5-14   c22.5,1.6,34.3,23.7,34.3,23.7c20,35.1,52.4,25,65.2,19.1c2-14.8,7.8-25,14.2-30.7c-49.7-5.8-102-25.5-102-113.5   c0-25.1,8.7-45.6,23-61.6c-2.3-5.8-10-29.2,2.2-60.8c0,0,18.8-6.2,61.6,23.5c17.9-5.1,37-7.6,56.1-7.7c19,0.1,38.2,2.6,56.1,7.7   c42.8-29.7,61.5-23.5,61.5-23.5c12.2,31.6,4.5,55,2.2,60.8c14.3,16.1,23,36.6,23,61.6c0,88.2-52.4,107.6-102.3,113.3   c8,7.1,15.2,21.1,15.2,42.5c0,30.7-0.3,55.5-0.3,63c0,6.1,4,13.3,15.4,11C415.9,449.1,480,363.1,480,261.7   C480,134.8,379.7,32,256,32z"/>
</svg>

<span class="new-window"><svg  height="8px"  style="enable-background:new 0 0 1000 1000;" version="1.1" viewBox="0 0 1000 1000" width="8px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<path d="M598 128h298v298h-86v-152l-418 418-60-60 418-418h-152v-86zM810 810v-298h86v298c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h298v86h-298v596h596z" style="fill-rule:evenodd;clip-rule:evenodd;fill:;"/>
</svg>
</span></a>



    </div>
  </div>
</nav>

    </div>
  </header>


    <main role="main">
      
  <article class="w-100 ph4 pb5 pb6-ns pt1 pt5-ns">
    <div class="order-0 w-20 dn db-l doc-menu" id="doc-menu">
      <div class="order-0 w-20 mt2 mb2" id="search-wrapper">
  <input id="search-box" type="search" placeholder="search" />
</div>

      
<nav role="navigation">
  <ul class="list pa0 nl2">
    
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".getting-started">入门（Getting Started）</a>
        <ul class="getting-started desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/getting-started.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/getting-started/what-you-need.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              准备工作（What You Need）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/getting-started/hello-world.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Hello World
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/getting-started/how-it-works.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              庖丁解牛
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".types">类型系统（Types）</a>
        <ul class="types desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/types.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/at-a-glance.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              类型系统概览
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/classes.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              类（Classes）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/primitives.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              基元类（Primitives）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/actors.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              并发单元（Actors）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/traits-and-interfaces.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              特征和接口（Traits and Interfaces）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/structs.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              结构体（Structs）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/type-aliases.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              类型别名（Type Aliases）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/types/type-expressions.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              类型表达式（Type Expressions）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".expressions">表达式（Expressions）</a>
        <ul class="expressions desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/literals.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              字面量（Literals）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/variables.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              变量（Variables）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/ops.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              运算符（Operators）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/arithmetic.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              算术运算符（Arithmetic）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/control-structures.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              流程控制（Control Structures）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/methods.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              方法（Methods）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/errors.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              异常处理（Errors）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/equality.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              比较（Equality in Pony）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/sugar.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              语法糖（Sugar）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/object-literals.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              匿名对象（Object Literals）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/expressions/partial-application.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              柯里化（Partial Application）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2  primary-color" data-target=".reference-capabilities">引用权能（Reference Capabilities）</a>
        <ul class="reference-capabilities desktopmenu animated fadeIn list pl0 bg-light-gray db">
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 primary-color ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/reference-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              引用权能（Reference Capabilities）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/guarantees.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              权能约束（Reference Capability Guarantees）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/consume-and-destructive-read.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              权能转让和破坏性读取（Consume and Destructive Read）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/recovering-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              权能借用（Recovering Capabilities）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/aliasing.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              别名引用（Aliasing）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/passing-and-sharing.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Passing and Sharing References
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/capability-subtyping.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              权能包含关系（Capability Subtyping）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/combining-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              权能合并（Combining Capabilities）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/arrow-types.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              箭头的用法（Arrow Types aka Viewpoints）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/reference-capabilities/capability-matrix.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              权能矩阵（Reference Capability Matrix）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".object-capabilities">对象权能模型（Object Capabilities）</a>
        <ul class="object-capabilities desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/object-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/object-capabilities/object-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              对象权能模型（Object Capabilities）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/object-capabilities/trust-boundary.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              边界信任（Trust Boundary）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".pattern-matching">模式匹配（Pattern Matching）</a>
        <ul class="pattern-matching desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/pattern-matching.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/pattern-matching/match.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              匹配表达式（Match Expressions）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/pattern-matching/as.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              as操作符（As Operator）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".generics">泛型（Generics）</a>
        <ul class="generics desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/generics.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/generics/generics-and-reference-capabilities.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              泛型和引用权能（Generics and Reference Capabilities）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/generics/generic-constraints.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              泛型约束（Constraints）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".packages">包（Packages）</a>
        <ul class="packages desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/packages.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/packages/package-system.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              包机制（Package System）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/packages/use-statement.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              包的使用方式（Use Statement）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/packages/standard-library.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              标准库（Standard Library）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".testing">测试（Testing）</a>
        <ul class="testing desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/testing.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/testing/ponytest.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Testing with Ponytest
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".c-ffi">C FFI</a>
        <ul class="c-ffi desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/c-ffi.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/c-ffi/calling-c.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Calling C from Pony
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/c-ffi/linking-c.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Linking to C Libraries
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/c-ffi/c-abi.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              C ABI
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/c-ffi/callbacks.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Callbacks
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".gotchas">陷阱（Gotchas）</a>
        <ul class="gotchas desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/gotchas.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/gotchas/divide-by-zero.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Divide by Zero
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/gotchas/garbage-collection.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Garbage Collection
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/gotchas/scheduling.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Scheduling
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/gotchas/side-effect-ordering-in-function-call-expressions.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Function Call Side Effects
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/gotchas/recursion.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Recursion
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".where-next">下一步？（Where Next?）</a>
        <ul class="where-next desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/where-next.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
        </ul>
      </li>
      
      <li class="f5 w-100 hover-bg-light-gray hover-accent-color-light fw8">
        <a href="javascript:void(0)" class="js-toggle dib w-100 link mid-gray hover-accent-color-light pl2 pr2 pv2 " data-target=".appendices">附录（Appendices）</a>
        <ul class="appendices desktopmenu animated fadeIn list pl0 bg-light-gray dn">
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              概述（Overview）
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/ponypath.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              PONYPATH
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/lexicon.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Lexicon
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/symbol-lookup-cheatsheet.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Symbol Lookup Cheatsheet
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/keywords.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Keywords
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/examples.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Examples
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/whitespace.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Whitespace
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/compiler-args.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Compiler Arguments
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/memory-allocation.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Memory Allocation at Runtime
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/garbage-collection.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Garbage Collection with Pony-ORCA
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/platform-dependent-code.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Platform-dependent code
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/error-messages.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              A Short Guide to Pony Error Messages
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/annotations.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Program Annotations
            </a>
          </li>
          <li class="f6 fw4">
            <a href="/pony-tutorial/appendices/serialisation.html" class="db link hover-bg-gray hover-white pl3 pr2 pv2 black ">
              Serialisation
            </a>
          </li>
        </ul>
      </li>
  </ul>
</nav>

    </div>
    <div class="flex-l" id="the-body">
      <div class="order-1 w-60-l mw9 ph0 ph5-ns mid-gray nested-copy-line-height no-underline nested-links nested-img nested-copy-seperator nested-blockquote mt0-ns" style="flex-grow:1;">
        <div class="order-0 mt4 w-100 center mw7" style="clear: both;">
          <a id="doc-menu-toggle" class="icon icon-menu" href="javascript:void(0)" onClick="hideShowDM()"></a>
        </div>
        <div class="documentation-copy center mw7" id="content">
          <header class="mt4 w-100">
            <p class="f6 b helvetica tracked">
                
              引用权能（REFERENCE CAPABILITIES）
            </p>
            <h1 class="f1 athelas mb1">概述（Overview）</h1>
          </header>

          <main class="nested-copy-line-height lh-copy serif f4 nested-links nested-img mid-gray pr4-l"><!-- raw HTML omitted -->
<p>我们已经介绍了Pony的类型系统的基础知识，然后是表达式，这一章关于引用权能将介绍Pony的类型系统的另一个特性。目前还没有任何主流编程语言具有引用权能。什么是引用权能?</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>引用权能是建立在<code>权能</code>这个概念上的。
权能是做<code>某事</code>的权限和功能。通常，<code>某物</code>涉及您可能希望访问的外部资源;比如文件系统或网络。这种能力的使用被称为对象权能，<a href="/pony-tutorial/object-capabilities.html">在下一章</a>中将对此进行讨论。</p>
<!-- raw HTML omitted -->
<p>Pony还有一种不同的功能，称为<code>引用权能</code>。<code>对象权能</code>是指被授予<code>使用对象执行操作的权限</code>，而<code>引用权能</code>是指拒绝<code>使用内存引用执行操作的权限</code>。例如，&ldquo;你可以访问这个内存，但只能读取它。你不能向它发送消息&rdquo;。这是一个引用权能，它拒绝你做事情。</p>
<!-- raw HTML omitted -->
<p>引用权能是Pony与众不同的核心。你可能还记得在本教程的介绍中我们说过的Pony:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<ul>
<li>它是类型安全的。类型安全。有一个数学<a href="http://www.ponylang.org/media/papers/opsla237-clebsch.pdf">证明</a>和一切。</li>
<li>它是内存安全的。这个带有类型安全，但仍然很有趣。没有悬空指针，没有缓冲区溢出，糟糕的是，这种语言甚至没有_null_的概念!</li>
<li>它是异常安全的。没有运行时异常。所有的异常都有定义的语义，它们总是被处理。</li>
<li>数据竞争。Pony没有锁或原子操作或任何类似的东西。相反，类型系统确保_at编译时您的并发程序永远不会发生数据竞争。因此，您可以编写高度并发的代码，并且永远不会出错。</li>
<li>没有死锁。这个很简单，因为Pony根本没有锁!所以它们肯定不会死锁，因为它们不存在。</li>
</ul>
<!-- raw HTML omitted -->
<p>引用权能使所有这些都成为可能。</p>
<!-- raw HTML omitted -->
<p>本章中的代码示例可能比较少，因为我们主要处理的是更高级的概念。在把这些想法付诸实践之前，试着至少通读一遍这一章。在完成本章之前，您应该已经开始了解什么是引用权能以及如何使用它们。如果你一开始就和他们斗争，不要担心。对于大多数人来说，这是一种思考代码的新方式，需要一段时间才能掌握。如果你在努力提高自己的知识水平时遇到了困难，一定要寻求帮助。一旦你使用了几周，功能上的问题就开始消失了，但在那之前可能是一个真正的斗争。别担心，我们都经历过这种挣扎。事实上，Pony网站上有一节专门介绍可以帮助学习引用权能的资源(<a href="https://www.ponylang.io/learn/#reference-capabilities">https://www.ponylang.io/learn/#reference-capabilities</a>)。无论如何，向Pony社区寻求帮助。我们在这里帮助您克服引用权能学习曲线。这并不容易。我们都知道。这对人们来说是一种新的思维方式，所以请伸出你的手(<a href="https://ponylang.zulipchat.com/#narrow/stream/189985-beginner-help">https://ponylang.zulipchat.com/#narrow/stream/189985-beginner-help</a>)。我们在等你的消息。</p>
<!-- raw HTML omitted -->
<p>害怕吗?不要。准备好了吗?好。让我们开始吧。</p>





          </main>

    <section class="flex-ns flex-wrap justify-around mt5">
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/reference-capabilities.html" class="link black dim">
        引用权能（Reference Capabilities）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>如果对象具有权能，我们该怎么来控制？比如如何表示该对象的 访问权限（access rights） ？
Pony中，可以用引用权能（reference capabilities）来处理。
权限只是权能的一部分 如果在UNIX系统中打开一个文件，会返回一个文件描述符，该文件描述符只是一个文件指向标识——并不是一个权能（描述符只体现了能没有体现权,描述符使可以访问文件，但是访问权呢？）。完整的权能：需要获得权限，然后指定文件路径和打开模式。例如:
chmod u+w /etc/passwd int fd = open(&#34;/etc/passwd&#34;, O_RDWR); 现在我们拥有了/etc/passwd文件的读写权，然后使用O_RDWR模式打开们见得到了一个文件描述符。访问授权、打开模式、文件描述符共同构成了一个权能。
在Pony中，所有被引用的数据都有一个类型和一个引用权能（reference capabilities）。实际上，引用权能（reference capabilities）是其类型的一部分。这允许你指定哪些对象可以与其他actor共享，并允许编译器检查你的逻辑是并发安全的。
基本概念（Basic concepts） 在引用权能（reference capabilities）变得有意义之前，您需要理解一些简单的概念。我们已经讨论过其中的一些，有些可能对你来说已经很明显了，但是在这里值得回顾一下。
共享可变数据非常困难
并发性的问题根源来自于共享可变数据。如果两个线程可以同时访问同一个数据，那么它们可能会同时修改它。这最多可能导致两个线程拥有不同版本的数据。在最坏的情况下，更新可能会交互不良，导致数据被垃圾覆盖。避免这些问题的常规做法是使用锁来防止同时发生数据更新。这会导致巨大的性能开销（上下文切换），并且一不小心就会导致bug。
不可变数据可以安全地共享
任何不可变的数据(即不会被修改数据)都可以安全地并发使用。因为它们永远不会更新，正是更新导致了并发性问题。
被隔离的数据是安全的
如果一个数据块只有一个对它的引用，那么我们称它为 被隔离的数据(isolated) 。因为只有一个对它的引用，所以不会被被多个线程共享，也就不存在并发问题。被隔离的数据可以在多个线程之间传递。只要同一时间只存在一个对它的引用，那么数据就是安全的，不会出现并发问题。
被隔离的数据有可以是复合类型
一个被隔离的数据（isolated）可以是一个字节，也可以是一个大型数据结构，并且在该结构中的各个对象之间有多个引用。对于隔离的数据来说，重要的是整个程序中只有一个单一的引用。我们讨论了数据结构的隔离边界。对结构进行隔离:
 外部必须只能有一个指向内部对象的引用。 外部可以有任意数量的引用，但它们都不能指向外部的对象。  每个actor都只会在一个线程中运行
actor内部的代码永远不会并发运行。在actor中，数据更新不会导致并发问题。只有当我们希望在actor之间共享数据时，才会遇到问题。
好吧，看来同时安全地共享数据确实很棘手，来看看引用权能（reference capabilities）是怎么做到的。
通过只共享不可变的数据和只交换被隔离的数据，我们可以拥有没有锁的安全并发程序。问题是要正确地做到这一点是非常困难的。如果您不小心挂起了对某些已提交的独立数据的引用，或者将已共享的内容更改为不可变的，那么一切都会出错。你需要的是编译器强迫你去实现你的承诺。小马引用权能（reference capabilities）允许编译器这样做。
类型限定符（Type qualifiers） 如果你使用过C/C++，您可能熟悉const，它是一个 类型限定符（type qualifier） ，告诉编译器不允许程序员修改某些东西。
A reference capability is a form of type qualifier and provides a lot more guarantees than const does! 引用权能（reference capabilities）是 type qualifier 的一种形式，它提供了比const更多的约束!</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/guarantees.html" class="link black dim">
        权能约束（Reference Capability Guarantees）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>因为类型系统的约束性，所以也需要了解下引用权能提供了哪些约束。
哪些语法是被禁止的？（What is denied） 接下来我们将讨论在引用权能的守护下，编译器会阻止哪些非法操作。也就是说：当你定义了一个具有引用权能的变量时，其他变量 不能 对它做什么?
首先我们需要区分：自身actor（变量所在的actor）、其他actor（外部actor）和任何actor（表示所有actor，包括自身actor和其他actor）。
需要知道一件重要事：多个actor会存在并发。如果两个actor都能读同一份数据，其中一个更改了数据，另一个actor也必须知道数据发生了变化。这将导致数据竞争，并产生对锁的需求。只有确保这种情况永远不会发生，Pony才能真正的消除锁。
还要牢记一点：单个actor中的代码总是顺序执行的。所以，在actor的内部对变量的访问不会产生数据竞争问题。
可变引用权能（Mutable reference capabilities） 可变的引用权能类型有iso、trn和ref。用这些引用权能标记的数据是可以修改的，它们可以用来读写对象。
 如果一个actor有一个iso变量，那么 任何actor都不能读写这个变量的数据。这表示iso变量是程序中惟一可以读写自身数据的变量，它具有读写唯一性（read and write unique）。 如果一个actor有一个trn变量，自身actor可读不可写，其他actor不能读写。这表示trn变量是程序中惟一可以修改自身数据的变量，但是自身actor持有的其他变量可能可以从该对象读取数据。它具备修改唯一性（write unique）。 如果一个actor有一个ref变量，只有自身actor可以读写，其他actor不能读写。其他actor想要读写该变量，只能借助消息机制（调用此actor的行为）来进行。  为什么自身actor内部可以安全的修改？ 因为其他actor无法对其读写。不可变的引用权能(Immutable reference capabilities) 不可变的引用权能是val和box。这些引用权能是不可变的，它们可以用于从对象中读取数据，而不是写入数据。
 如果一个actor有一个val变量，那么任何actor不能修改它。这表示它无法被修改。它的数据是全局不可变（globally immutable）的。 如果一个actor有一个box变量，那么其他actor不能修改她，但可以读取，而自身actor中的其他变量才可以修改(尽管不是同时写入)。无论哪种情况，我们读取变量都是安全的。这类对象是局部不可变（localy immutable）的。  为什么可以读取不能修改? 因为这些引用权能只会阻止其他actor的修改操作，但是不会阻止其他actor的读取操作。因为多个actor同时读取一个对象是安全的，所以这样做没问题。
不透明的引用权能（Opaque reference capabilities） 不透明（opaque）的引用权能只有一种，那就是tag。tag变量对其他变量没有任何约束。它既不能用于从对象中读取数据，也不能用于从对象中写入数据。因此被称为 不透明（opaque） 。
即便如此，它仍然是有用的：你可以用它做身份比较，也可以在它上面调用行为和方法，只需要一个tag接收器。
为什么编译器不允许对tag进行读写？ 这是Pony的一种取舍，因为在在tag调用行为时，我们无法停止这一调佣操作。你可以想象一下这样的情况：如果我们一边用它来调用一些操行为，但是同时我们又其他actor对其修改，那就可能会触发数据竞争的情况。</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/consume-and-destructive-read.html" class="link black dim">
        权能转让和破坏性读取（Consume and Destructive Read）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>权能是Pony的一个重要部分，就是能够说&quot;我已经完成了这件事。&rdquo; 我们将介绍处理这种情况的两种方法:转让变量和破坏性读取。
转让变量（Consuming a variable） 有时，你希望将对象从一个变量转移到另一个变量。你不希望为对象创建一个新名字，只是从某个现有名称移动到另一个不同的名字。
你可以使用转让（consume）表达式来完成。当你转让（consume）一个变量时，将从中取出该变量的值，实际上是将该变量清空。在向该变量写入新值之前，任何代码都不能再次读取该变量。使用局部变量或参数允许你使用相同类型的别名，即使它是iso或trn。例如:
fun test(a: Wombat iso) =&gt; var b: Wombat iso = consume a // Allowed! 此处编译器非常清楚a已经被你转让出去了，该变量不能再次使用，如果你尝试使用，编译器就会报错。
fun test(a: Wombat iso) =&gt; var b: Wombat iso = consume a // Allowed! var c: Wombat tag = a // Not allowed! 上面示例中，当你试图把a赋值给c时，编译器会报错。
可以转让（consume）一个字段吗? 当然不行！被转让（consume）意味着被置空，也就是说它会没有值。我们无法确保对象的其他别名不会访问该字段。如果试图访问一个空字段，程序会崩溃。但是还有有一种情况你需要知道：破坏性读取（destructive read）。
破坏性读取（Destructive read） 还有另一种方法可以将数据从一个变量移动到另一个变量。在前面，我们讨论了Pony中的赋值如何返回左侧的旧值，而不是新值。这叫做破坏性读取（destructive read），我们可以用它来转让任何数据，就算是字段也没问题。
class Aardvark var buddy: Wombat iso new create() =&gt; buddy = recover Wombat end fun ref test(a: Wombat iso) =&gt; var b: Wombat iso = buddy = consume a // Allowed!</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/recovering-capabilities.html" class="link black dim">
        权能借用（Recovering Capabilities）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>借用（recover）表达式允许你提升（lift）结果的引用权能。可变引用权能(iso、trn或ref)可以成为_any_引用权能，而不可变引用权能(val或box)可以成为任何不可变或不透明的引用权能。
它有哪些用途？（Why is this useful?） 借用（recover）最直接的用法是将一个iso变量传递给另一个actor。但是它也可以用在很多其他的事情上，比如:
 创建循环的不可变数据结构。也就是说，你可以在借用（recover）表达式中创建一个复杂的可变数据结构，将结果ref&quot;提升&quot;为val。 借用（Borrow）一个iso作为ref，对它进行一系列复杂的可变操作，然后再次以iso的形式返回。 从iso中提取（Extract）一个可变字段，并将其作为iso返回。  借用表达式的示例 借用（recover）表达式可以封装一个表达式列表，以end结尾，就像这样:
recover Array[String].create() end 借用表达式返回的是Array[String] iso，而不是Array[String] ref。为什么是iso而不是其他可变引用权能？因为当你不指定权能时，iso是默认的引用权能类型。所有可变引用权能的默认值都是iso，而所有不可变引用权能的默认值都是val。
下面是一个来自标准库的更复杂的例子:
recover var s = String((prec + 1).max(width.max(31))) var value = x try if value == 0 then s.push(table(0)?) else while value != 0 do let index = ((value = value / base) - (value * base)) s.push(table(index.usize())?) end end end _extend_digits(s, prec') s.append(typestring) s.append(prestring) _pad(s, width, align, fill) s end 它从format/_FormatInt创建了一个String ref，用它做了一系列操作，最后返回一个String iso类型。</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/aliasing.html" class="link black dim">
        别名引用（Aliasing）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>别名引用（Aliasing） 是指在一个actor内部对同一对象会有多个引用。可能是变量，也可能是字段。
在其他编程语言中，别名引用很常见。只需要把一个变量赋值给另一个变量，就得到了一个别名。只要被赋值的变量与原始变量具有相同的类型(或某些超类型)，操作就没问题。
在Pony中，这种操作只适用于一些引用权能，不是所有引用权能都支持这么做。
别名引用和引用约束（Aliasing and deny guarantees） 下面示例引用操作被编译器阻止的原因是iso引用权能的读写唯一性约束，拒绝了其他iso变量引用自身数据。也就是说，只能有一个iso变量指向任何给定的对象数据。trn也是一样。
fun test(a: Wombat iso) =&gt; var b: Wombat iso = a // Not allowed! 这里我们有一些函数传递给一个iso权能类型的Wombat对象。为a创建一个b的别名，将破坏引用权能约束，因此编译器将阻止我们。
我可以将iso别名为什么?由于iso表示任何其他变量都不能被_any_ actor用来读写该对象，所以我们只能为既不能读也不能写的iso创建别名。幸运的是，我们有一个引用权能:&rsquo; tag &lsquo;。所以我们可以这样做，编译器会很高兴:
fun test(a: Wombat iso) =&gt; var b: Wombat tag = a // Allowed! 那混叠trn呢?因为trn表示任何其他变量都不能被任何actor用来写入该对象，所以我们需要一些不允许写入但也不阻止trn变量写入的东西。幸运的是，我们还有一个引用权能可以做到这一点:box。所以我们可以这样做，编译器会很高兴:
fun test(a: Wombat trn) =&gt; var b: Wombat box = a // Allowed! 那混叠其他东西呢?对于iso和trn，引用权能机制约束别名必须放弃某些权能(iso的读和写，trn的写)。对于其他功能(&rsquo; ref &lsquo;、&rsquo; val &lsquo;、&rsquo; box &lsquo;和&rsquo; tag &lsquo;)，别名允许相同的操作，所以这样的引用可以作为它自己的别名。
什么算假名?（What counts as making an alias?） 有三件事可以算作别名:</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/passing-and-sharing.html" class="link black dim">
        Passing and Sharing References
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>引用权能让我们在actor之间可以安全地传递可变数据，也可以在actor之间可以安全地共享不变数据。不仅如此，它们还提供了安全的方法进行数据处理，不需要复制，不需要加锁，并且不会有运行时开销。
Passing 对于要可变的对象，我们需要确保没有其他actor可以对该对象读写。有三种可变引用权能(iso、trn和ref)都可以对此进行限制。
但是如果我们想要将一个可变对象从一个actor传递给另一个actor呢?为此，我们需要确保正在发送（sending）可变对象的actor也give up从该对象读写的权能。
这正是iso所做的。它是读写唯一的，一次只能有一个可用于读写的引用。如果您将一个iso对象发送给另一个参与者，您将放弃从该对象读写的权能。
那么当我想要在actor之间传递一个可变对象时，我应该使用iso吗?__是的!如果你不需要传递它，你可以使用ref代替。
Sharing 如果你想在参与者之间共享一个对象，那么我们必须遵守如下约束:
 no actor可以写对象，在这种情况下_any_ actor可以从对象中读取，或者 只有_one_ actor可以对对象进行写操作，在这种情况下_other_ actor既不能对对象进行读操作，也不能对对象进行写操作。  第一个约束就是val所做的。它具有全局不可变性，所以我们知道没有actor可以修改那个对象。因此，您可以自由地将val对象发送给其他参与者，而不需要放弃从该对象读取数据的权能。
那么当我想要在参与者之间共享一个不可变的对象时，我应该使用val吗?__是的!如果你不需要共享它，你可以使用ref代替，或box如果你想它是不可变的。
第二个保证是tag的权能。不是关于只写一个参与者的部分(这是由任何可变引用权能保证的)，而是关于不能读写对象的部分。这意味着您可以自由地将tag对象传递给其他参与者，而不需要放弃从该对象读写的权能。
如果另一个参与者不能读写字段，那么将tag引用发送给另一个参与者又有什么意义呢?因为tag可以被用来识别目标，有时这就是你所需要的。另外，如果对象是一个参与者，即使您只有一个tag，您也可以对其调用行为。
那么当我想要在actor之间共享可变对象的身份时，我应该使用tag吗?__是的!或者，实际上，任何东西的恒等式，不管是可变的，不可变的，甚至是一个行动者。
无法发送的引用权能 你可能已经注意到我们并没有提到trn，ref，或者box作为你可以发送给其他actor的东西。那是因为你做不到。他们不会为了安全而做出我们需要的约束。
那么什么时候应该使用这些引用权能呢?
*当你需要能够随着时间改变一个对象时，使用ref。另一方面，如果您的程序在使用不可变类型时不会变得更慢，那么您可能希望使用val。 *当你不关心对象是可变的还是不可变的时候，使用box。换句话说，你想要能够阅读它，但你不需要给它写信或与其他演员分享它。 *当你想要改变一个对象一段时间，但你也想让它 全局不可变（global immutable） 以后使用trn。</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/capability-subtyping.html" class="link black dim">
        权能包含关系（Capability Subtyping）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>子类型是关于_替换性的。也就是说，如果我们需要提供某一种类型，我们还可以替代什么类型?其中包括引用权能。
Simple substitution 首先，让我们讨论替换，而不必担心临时类型(^)或别名类型(!)。符号&lt;:表示是的子类型，或者可以被替换。
 iso &lt;: trn。iso是_read和write unique_， trn是_write unique_，所以用iso代替trn是安全的。 trn &lt;: ref。一个trn是可变的，也_write unique_。ref是可变的，但不能保证唯一性。用trn代替ref是安全的。 trn &lt;: val。这个很有趣。trn是_write unique_， val是全局不可变的，那么为什么用trn代替val是安全的呢?关键是，为了做到这一点，你必须放弃你所拥有的一切。如果你放弃了_only_变量可以写一个对象，你知道没有变量可以写它。这意味着它是全局不变的。 ref &lt;: box。ref约束可以保证没有其他actor可以读写对象。box只是确保没有其他actor可以写对象，所以用ref代替box是安全的。 val &lt;: box。一个val约束 _no_actor，即使是这个，也不能写对象。一个box只是约束没有其他actor可以写对象，所以用val代替box是安全的。 box &lt;: tag。box约束限制没有其他参与者可以写入对象，而tag则完全没有提供约束性保证，所以用box替换tag是安全的。  子类型化_transitive_。这意味着，由于iso &lt;: trn和trn &lt;: ref和ref &lt;: box，我们也得到iso &lt;: box。
Aliased substitution 现在让我们考虑一下当我们有一个引用权能的别名时会发生什么。例如，如果我们有一些iso，并对其进行别名处理(不执行消费或破坏性读取)，则得到的类型是iso!,而不是iso。
*iso !&lt;:tag。这是一个相当大的变化。而不是像iso这样的所有东西的子类型，唯一的东西是iso!是tag的子类型。这是因为iso仍然存在，并且仍然是_read和write unique_。任何别名既不能从对象中读取，也不能从对象中写入。这意味着iso!'只能是tag的子类型。 *trn!&lt;:box。这也是一个变化，但并不是很大的变化。因为trn只是 _write unique_ ，所以别名可以从对象中读取，但是别名不能写入对象。这意味着我们可以有box或val别名-除了val约束和限制 _no_ alias可以写入对象!因为我们的trn仍然存在，并可以写入对象，val别名将打破val作出的约束限制。所以一个ref!只能是box的子类型(及及物动词tag)。 *ref!&lt;:ref。由于ref只约束和限制 _other_ actor既不能从对象中读取也不能从对象中写入，所以可以在同一个actor中创建更多ref别名。 *val!&lt;:val。因为val只能约束和限制 _no_ actor可以写入对象，所以可以使用更多的val别名，因为它们也不能写入对象。 *box!&lt;:box。一个框只能约束其他actor不能写对象。val和ref都做了保证，那么为什么box只能别名为box呢?这是因为我们不能做更多的保证当我们别名的东西。这意味着box只能别名为box。 *tag!&lt;:tag。一个tag根本没有提供什么约束。就像box一样，我们不能在创建新别名时做更多的约束，因此tag只能作为tag的别名。
Ephemeral substitution 最后要考虑的情况是当我们有临时引用权能时。例如，如果我们有一些iso，我们'消费'它或做一个破坏性的阅读，我们得到的类型是iso^，而不是iso。
 iso^ &lt;: iso。这很简单。当我们给一个iso^一个名字时，通过把它赋值给某个东西或者把它作为参数传递给某个方法，它就会失去^而变成一个普通的旧的iso。我们知道我们已经放弃了之前的iso，所以换一个新的是安全的。 trn^ &lt;: trn。这和iso^ 完全一样。约束性是较弱的(write uniqueness_而不是_read和write uniquess)，但它的工作方式是一样的。 ref^ &lt;: ref 和ref ^ &lt;: ref和ref &lt;: ref ^。这里，我们有另一个例子。a ref不仅是a ref的子类型，它也是a ref的子类型。这是怎么回事?</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/combining-capabilities.html" class="link black dim">
        权能合并（Combining Capabilities）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>当一个对象的一个字段被读取时，它的引用权能既取决于字段的引用权能，也取决于_origin__的引用权能，也就是说，从该字段被读取的对象。
这是因为对其字段所做的所有约束性都必须对其字段进行维护。
观点适应（Viewpoint adaptation） 将原始权能和字段权能相结合的过程称为 视角适应 。也就是说，origin 有一个 viewpoint ，并且只能从那个 viewpoint 中访问它的字段。
下表展示了不同权能的 字段 看起来是如何与每个权能的 源 相匹配的。
    ▷ iso field trn field ref field val field box field tag field     iso origin iso tag tag val tag tag   trn origin iso trn box val box tag   ref origin iso trn ref val box tag   val origin val val val val val tag   box origin tag box box val box tag   tag origin n/a n/a n/a n/a n/a n/a     例如，如果你有一个&rsquo; trn &lsquo;原点，你读了一个&rsquo; ref &lsquo;字段，你会得到一个&rsquo; box &lsquo;结果:</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/arrow-types.html" class="link black dim">
        箭头的用法（Arrow Types aka Viewpoints）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>当我们讨论了 引用权能组合 和 观点适应 时，我们处理了我们知道来源的引用权能的情况。然而，有时我们并不知道原点的精确引用权能。
当这种情况发生时，我们可以编写一个适合类型为 的视角 ，我们称其为一个 型箭头 ，因为我们用一个-&gt;来编写它。
Using this-&gt; as a viewpoint 带有box接收器的函数也可以用ref接收器或val接收器来调用，因为它们都是box的子类型。有时，我们希望能够讨论一种类型来考虑这一点。例如:
class Wombat var _friend: Wombat fun friend(): this-&gt;Wombat =&gt; _friend 在这里，我们有一个袋熊，每个袋熊都有一个同样是袋熊的朋友(幸运的袋熊)。事实上，它是一个Wombat ref，因为ref是Wombat的默认引用权能(因为我们没有指定一个)。我们还有一个函数返回那个朋友。它有一个box接收器(因为box是一个函数的默认接收器引用权能，如果我们不指定它的话)。
所以返回类型通常是袋熊盒子。为什么?因为，正如我们前面看到的，当我们从一个box源读取一个ref字段时，我们会得到一个box。在本例中，原点是接收器，它是一个方框。
但是等等!如果我们想要一个函数，在接收方是ref时返回Wombat ref，在接收方是val时返回Wombat val，在接收方是box时返回Wombat box，那该怎么办?我们不想把这个函数写三遍。
我们使用this-&gt;！在这种情况下，this-&gt;Wombat。它的意思是&quot;接收者看到的Wombat ref&rdquo;。
我们知道在 call站点上 ，接收方的实际引用权能是什么。因此，当函数被调用时，编译器知道它需要知道的一切，以使其正确。
Using a type parameter as a viewpoint 我们还没有涉及泛型，所以这看起来有点奇怪。当我们讨论泛型(即参数化类型)时，我们将再次讨论这个问题，但是我们在这里提到它是为了完整性。
另一种情况是，我们不知道某个东西的精确引用权能，即我们是否使用了类型参数。下面是来自标准库的一个例子:
class ListValues[A, N: ListNode[A] box] is Iterator[N-&gt;A] 这里，我们有一个ListValues类型，它有两个类型参数a和N。此外，N还有一个约束:它必须是ListNode[a] box的子类型。这很好，但我们也说ListValues[A, N]提供了Iterator[N-&gt;A]。这就是有趣的地方:我们提供了一个接口，让我们对类型N-&gt;A的值进行迭代。
这意味着我们将返回类型为A的对象，但是引用权能将与类型为N的对象看到类型为A的对象相同。
Using box-&gt; as a viewpoint 还有一种使用箭头类型的方法，它也与泛型有关。有时，我们希望讨论某个类型参数，因为它是由某个未知类型看到的，as long as该类型可以读取type parameter 。
换句话说，未知类型将是box的子类型，但我们只知道这些。下面是来自标准库的一个例子:
interface Comparable[A: Comparable[A] box] fun eq(that: box-&gt;A): Bool =&gt; this is that fun ne(that: box-&gt;A): Bool =&gt; not eq(that) 在这里，我们说一个东西是‘Comparable[A]’，当且仅当它有函数‘eq’和‘ne’，而这些函数有一个类型为‘box-&gt;A’的参数并返回一个‘Bool’时。换句话说，不管A与什么有关，我们只需要能够读懂它。</p>
      
    </div>
  </div>
</div>
</div>
      
        <div class="relative w-100 mb4 bg-white"><div class="relative w-100 mb4 bg-white nested-copy-line-height">
  <div class="bg-white mb3 pa4 gray overflow-hidden">
    <h1 class="f3 near-black">
      <a href="/pony-tutorial/reference-capabilities/capability-matrix.html" class="link black dim">
        权能矩阵（Reference Capability Matrix）
      </a>
    </h1>
    <div class="nested-links f5 lh-copy nested-copy-line-height">
      
        <p>此时，您很可能已经阅读了本章前面的部分，仍然对引用权能之间的关系感到困惑。这是好的!当我们学习小马的这一部分时，我们也都很挣扎。一旦你开始编写小马代码，你就会对它们有一个更好的直觉。
与此同时，如果您仍然觉得本章中的所有花絮仍在您的脑海中乱作一堆，那么有一种通常使用Pony提供的资源可以为您提供一种更直观的表示:即 引用权能矩阵（reference capability matrix）。
它也是Pony中每个权能背后的概念的起源，意思是每个权能如何拒绝它所引用的某些属性——换句话说，这约束了权能的山城。在展示矩阵之前，我们会解释这到底是什么意思。
Local and global aliases 首先，我们要澄清&quot;本地&quot;和&quot;全局&quot;别名的含义。
局部别名是对存在于同一参与者中的相同变量的引用。当你传递一个值的时候，它不是一个actor行为的参数，这是我们使用的别名。
另一方面，全局别名是对可以存在于_different actor中的相同变量的引用。也就是说，它描述了两个或多个参与者如何与同一个引用交互的属性。
Pony中的每个引用权能实际上是一对局部约束和全局约束。例如，ref不否认参与者内部的任何读/写权能，但否认其他参与者对该引用的读或写权能。
您可能还记得在[Reference Capability guarantee](guarantee .md)一节中提到，易变的引用不能在参与者之间安全地共享，而不可变的引用可以由多个参与者读取。一般来说，全局属性总是与引用的局部属性具有相同或更严格的限制—全局拒绝的内容也必须在局部拒绝。例如，不可能以全局或本地别名写入不可变引用。也不可能从不透明的引用tag读取或写入。因此，局部和全局别名的某些组合是不可能的，并且没有指定的权能。
Reference capability matrix 言归正传，下面是引用权能矩阵:
      Deny global read/write aliases Deny global write aliases Don&rsquo;t deny any global aliases     Deny local read/write aliases iso     Deny local write aliases trn val    Don&rsquo;t deny any local aliases ref box tag     (Mutable) (Immutable) (Opaque)     在矩阵的上下文中，&ldquo;拒绝某个权能&quot;意味着不允许该引用的任何其他别名执行该操作。例如，由于trn拒绝其他本地写别名(但允许读)，所以这是惟一允许对对象进行写的引用;由于它同时拒绝向其他参与者写入和读取别名，所以在这个actor中写入别名是安全的，因此是可变的。由于box不会破坏trn所做的任何约束(允许本地读取，但禁止全局写入)，所以我们可以为trn引用创建box别名。</p>
      
    </div>
  </div>
</div>
</div>
      
    </section>
        </div>
        <div id="search-results" class="center mw7 dn"></div>
      </div>
    </div>
  </article>

    </main>
    

<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/languages/pony.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.5/lunr.min.js"></script>

<script async defer src="https://buttons.github.io/buttons.js"></script>

<script>
  var toggleBtns = document.getElementsByClassName('js-toggle')
  for (var i = 0; i < toggleBtns.length; i++) {
    toggleBtns[i].addEventListener('click', toggleClass, false)
  }

  var myToggleBtns = document.getElementsByClassName('hide-show-toggle')
  for (var i = 0; i < myToggleBtns.length; i++) {
    myToggleBtns[i].addEventListener('click', hideShow, false)
  }

function hideShowDM() {
  var menu = document.getElementById("doc-menu")
  var thebody = document.getElementById("the-body")
  if (window.getComputedStyle(menu).display == "none") {
    menu.style.display = "block";
    thebody.style.left = "300px";
  } else {
    menu.style.display = "none";
    thebody.style.left = "0px";
  }
}

function hideShowCM() {
  var menu = document.getElementById("context-menu")
  if (window.getComputedStyle(menu).display == "none") {
    menu.style.display = "block";
  } else {
    menu.style.display = "none";
  }
}

function toggleClass() {
  
  var content = this.dataset.target.split(' ')
  
  var mobileCurrentlyOpen = document.querySelector('.mobilemenu:not(.dn)')
  var desktopCurrentlyOpen = document.querySelector('.desktopmenu:not(.dn)')
  var desktopActive = document.querySelector('.desktopmenu:not(.dn)')

  
  for (var i = 0; i < content.length; i++) {
    var matches = document.querySelectorAll(content[i]);
    
    [].forEach.call(matches, function(dom) {
        dom.classList.contains('dn') ?
        dom.classList.remove('dn') :
        dom.classList.add('dn');
         return false;
       });
        
      if (mobileCurrentlyOpen) mobileCurrentlyOpen.classList.add('dn')
      if (desktopCurrentlyOpen) desktopCurrentlyOpen.classList.add('dn')
      if (desktopActive) desktopActive.classList.remove('db')

    }
  }

var Pony = {};


Pony.Search = (function() {
  var that = {}
  that.lunrIndex = undefined;
  that.pages = [];

  that.doSearch = function(query) {
    var resultsContainer = $('#search-results');
    var contentContainer = $('#content');
    
    var results = this.lunrIndex.search(query).map(function(result) {
      
        return {
            page: that.pages[result.ref],
            metadata: result.matchData.metadata
        };
    });

    
    resultsContainer.empty();
    resultsContainer.append(
        $("<header>", {class: "mt4 w-100"}).append(
            $("<p>", {class: "f6 b helvetica tracked", text: "SEARCH RESULTS"}))
    );
    var resList = $("<ul>", {id: "search-result-list"});

    
    results.slice(0, 100).forEach(function(result) {
        var res = $("<li>");
        var div = $("<div>", {class: "search-result"});
        div.append($("<a>", {
          href: result.page.uri,
          text: result.page.title,
          class: "search-result-title"
        }));
        var p = $("<p>", {
            class: "search-result-summary"
        });
        var highlighted = that.highlightResult(result.page.summary, result.metadata);
        p.append(highlighted);
        div.append(p);
        res.append(div);
        resList.append(res);
    });
    resultsContainer.append(resList);

    
    contentContainer.addClass("dn");
    resultsContainer.removeClass("dn");
  };

  that.highlightResult = function(text, metadata) {
      var span = $("<span>");
      for (var key in metadata) {
        var summary_metadata = metadata[key]["summary"];
        if (summary_metadata !== undefined && summary_metadata["position"] !== undefined) {
            var position_metadata = summary_metadata["position"];
            var last_pos = 0;
            summary_metadata["position"].forEach(function(elem) {
                span.append(
                    $("<span>", {text: text.slice(last_pos, elem[0])})
                );
                span.append(
                    $("<span>", {
                        class: "highlighted",
                        text: text.slice(elem[0], elem[0] + elem[1])})
                );
                last_pos = elem[0] + elem[1];
            });
            span.append(
                $("<span>", {text: text.slice(last_pos, text.length)})
            );
        } else {
          span.text(text);
        }
      }
      return span;
  };

  that.initLunr = function(onSuccess) {
      $.getJSON("/index.json")
        .done(function(index) {
           
           that.pages = index;
           that.lunrIndex = lunr(function() {
             this.metadataWhitelist = ['position']; 
             this.field("title", { boost: 10 });
             this.field("tags", { boost: 5 });
             this.field("categories", { boost: 5 });
             this.field("content");
             this.field("summary", {boost: 0});
             this.ref("i");

             index.forEach(function (page, idx) {
                 page["i"] = idx;
                 this.add(page)
               },
               this
             );
           });
           onSuccess();
        })
        .fail(function(jqxhr, textStatus, error) {
          var err = textStatus + ", " + error;
          console.error("Error getting search index file:", err);
        });
    }
  that.setUpSearchUI = function() {
    $('#search-box').keyup(function() {
        var query = $(this).val();
        if (query.length < 2) {
            if (query.length == 0) {
                $('#content').removeClass('dn');
                $('#search-results').empty().addClass('dn');
            }
            return;
        }
        if (that.lunrIndex === undefined) {
            that.initLunr(function () {
              that.doSearch(query);
            });
        } else {
            that.doSearch(query);
        }
    });
  }
  return that;
})();




$(document).ready(function() {
  Pony.Search.setUpSearchUI();
});
</script>

  </body>
</html>
